
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>

#include <stdlib.h>
#include "ConnectorTest.h"
#include "MakeMsgBlock.h"
#include "md5.h"

void create_account(ConnectorService *service);
void log_in(ConnectorService *service);
void log_out(ConnectorService *service);
void enter_room(ConnectorService *service,int room);
void exit_room(ConnectorService *service);
void switch_room(ConnectorService *service);
void enter_table(ConnectorService *service);
void exit_table(ConnectorService *service);
void select_operation(MessageBlock *mb);
void test_packet(ConnectorService *service);

std::string account="test1";
std::string pwd="123456";
int roleid=1;

ConnectorService *service=NULL;//new ConnectorService();

int main(int argc,char *argv[])
{
	int port = 8001;
	int room = 1;

	if(argc<2)
	{
		std::cout<<"input account"<<std::endl;
		return 0;
	}
	account = argv[1];

	if(argc>2)
	{
		room = atoi(argv[2]);
	}
	if(argc > 3)
	{
		port = atoi(argv[3]);
	}
	Reactor *rea = Reactor::instance();
	rea->implement(new EpollReactor(1024,1024));
	service=new ConnectorService();
	service->reactor(rea);
	GateConnector<ConnectorService> conn;
	conn.open(service->reactor(),false);
	if(conn.connect("127.0.0.1",port,service)!=0)
	{
		std::cout<<"connect failed1:"<<strerror(errno)<<std::endl;
		return 0;
	}

	ConnectorService *db=new ConnectorService();
	db->reactor(rea);
	GateConnector<ConnectorService> dbconn;
	dbconn.open(db->reactor(),false);
	if (dbconn.connect("127.0.0.1", 8003, db) != 0)
	{
		std::cout << "connect failed2:" << strerror(errno) << std::endl;
		return 0;
	}

	struct timeval timeout = {3,0};
	setsockopt(service->peer()->get_handle(),SOL_SOCKET,SO_RCVTIMEO, (char*)&timeout,sizeof(struct timeval));

	service->peer()->disable(O_NONBLOCK);
	int cmd = 0;

	while (true)
	{
		std::cout<< "input cmd:"<<std::endl;
		std::cin >> cmd;
		if (cmd == 12000002)
		{
			create_account(db);
		}
		else if (cmd == 10000001)
		{
			log_in(service);
		}
		else if(cmd==10000002)
		{
			log_out(service);
		}
		else if(cmd==10000003)
		{
			enter_room(service,room);
		}
		else if(cmd==10000004)
		{
			exit_room(service);
		}
		else if(cmd==10000005)
		{
			switch_room(service);
		}
		else if (cmd == 10000006)
		{
			enter_table(service);
		}
		else if (cmd == 10000007)
		{
			exit_table(service);
		}
		else if(cmd==1)
		{
			test_packet(service);
		}
		else if(cmd==2)
		{
			log_in(service);
			enter_room(service,room);
			enter_table(service);
		}
		else
		{
			break;
		}
		usleep(500);
	}
	sleep(10);
	//::close(fd);
	service->close();
	return 0;
}

void create_account(ConnectorService *service)
{
	MessageBlock mb(512);
	mb << 0;
	mb << 12000002;
	mb << 0;
	mb << 1001;
	mb << account;
	mb << pwd;
	mb << 1;
	char *p=mb.base_ptr();
	*p = mb.data_len();

	//int send_len =::send(fd,(void*)mb.rd_ptr(),mb.data_len(),0);
	int send_len =service->send_msg(&mb,mb.data_len());
	std::cout << "send len:"<<send_len<<std::endl;

	MessageBlock recv_mb(4096);
	//int recv_len =::recv(fd,recv_mb.wr_ptr(),recv_mb.size(),0);
	int recv_len = service->recv_msg(&recv_mb,recv_mb.size(),MSG_WAITALL);
	if(recv_len<0)
	{
		std::cout << "recv len error:"<<recv_len<<std::endl;
	}
	std::cout << "recv len:"<<recv_len<<std::endl;
}

void log_in(ConnectorService *service)
{
	//char password[128]={0};
	//Md5::md5(password,(char*)pwd.c_str());

	//std::cout <<"pwd:"<<password<<std::endl;
	MessageBlock mb(512);
	mb << 0;
	mb << 10000001;
	mb << 0;
	mb << account;
	mb << pwd;//std::string(password);
	mb << roleid;
	char *p=mb.base_ptr();
	*p = mb.data_len();

	int len = 0,cmd=0,remain=0;
	std::string account,psd;
	mb >> len >> cmd >> remain >> account >> psd;
	std::cout << account <<"--"<< psd <<std::endl;
	mb.reset_rd_ptr();

	//int send_len =::send(fd,(void*)mb.rd_ptr(),mb.data_len(),0);
	int send_len =service->send_msg(&mb,mb.data_len());
	std::cout << "send len:"<<send_len<<std::endl;

	//struct timeval timeout = {3,0};
	//setsockopt(service->peer()->get_handle(),SOL_SOCKET,SO_RCVTIMEO, (char*)&timeout,sizeof(struct timeval));
	MessageBlock recv_mb(4096);
	while(true)
	{
		recv_mb.reset();
		int recv_len = service->recv_msg(&recv_mb,recv_mb.size(),MSG_NOSIGNAL);
		if(recv_len<=0)
		{
			std::cout << "recv len error:"<<recv_len <<":"<<strerror(errno)<<std::endl;
			break;
		}

		int ret_len=0,ret_cmd=0,result=0;
		recv_mb >> ret_len >> ret_cmd >> result;
		std::cout << "recv len:"<<recv_len<<"-ret_len:"<<ret_len
				<<"-ret_cmd:"<<ret_cmd<<"-result:"<<result<<std::endl;
	}

}

void log_out(ConnectorService *service)
{
	MessageBlock mb(512);
	mb << 0;
	mb << 10000002;
	mb << 0;
	char *p=mb.base_ptr();
	*p = mb.data_len();

	int len = 0,cmd=0,remain=0;
	std::string account,psd;
	mb >> len >> cmd >> remain >> account >> psd;
	std::cout << account <<"--"<< psd <<std::endl;
	mb.reset_rd_ptr();

	//int send_len =::send(fd,(void*)mb.rd_ptr(),mb.data_len(),0);
	int send_len =service->send_msg(&mb,mb.data_len());
	std::cout << "send len:"<<send_len<<std::endl;

	MessageBlock recv_mb(4096);

	while(true)
	{
		recv_mb.reset();
		int recv_len = service->recv_msg(&recv_mb,recv_mb.size(),0);
		if(recv_len<0)
		{
			std::cout << "recv len error:"<<recv_len<<std::endl;
		}
		int result=0;
		recv_mb >> len >> cmd >> result;
		std::cout << "recv len:"<<recv_len<<"-len:"<<len
				<<"-cmd:"<<cmd<<"-result:"<<result<<std::endl;
	}

}
void enter_room(ConnectorService *service,int room)
{
	MessageBlock mb(512);
	mb << 0;
	mb << 10000003;
	mb << 0;
	mb << room;
	char *p=mb.base_ptr();
	*p = mb.data_len();

	//int send_len =::send(fd,(void*)mb.rd_ptr(),mb.data_len(),0);
	int send_len =service->send_msg(&mb,mb.data_len());
	std::cout << "send len:"<<send_len<<std::endl;

	MessageBlock recv_mb(4096);

	while(true)
	{
		recv_mb.reset();
		int recv_len = service->recv_msg(&recv_mb,recv_mb.size(),0);
		if(recv_len<0)
		{
			std::cout << "recv len error:"<<recv_len<<std::endl;
			break;
		}
		int len=0,cmd=0,result=0;
		recv_mb >> len >> cmd >> result;
		std::cout << "recv len:"<<recv_len<<"-len:"<<len
				<<"-cmd:"<<cmd<<"-result:"<<result<<std::endl;
//		if (recv_len >= 700)
//		{
//			int desk_num = 0, desk_id = 0, desk_status = 0, sit_num = 0,
//					sit_id = 0, role_id, role_status = 0;
//			std::string name = "";
//			recv_mb >> desk_num;
//			for (int i = 0; i < desk_num; i++)
//			{
//				recv_mb >> desk_id >> desk_status >> sit_num; //>>sit_id>>role_id;
//				for (int j = 0; j < sit_num; j++)
//				{
//					recv_mb >> sit_id >> role_id;
//					if (role_id != 0)
//					{
//						recv_mb >> role_status >> name;
//					}
//					char log[512]={0};
//					sprintf(log,"[%d][%d][%d][%d][%d][%d][%d][%d][%s]",
//							recv_mb.data_len(),desk_num,desk_id,desk_status,
//							sit_num,sit_id,role_id,role_status,name.c_str());
//					std::cout<<log<<std::endl;
//				}
//			}
//		}
	}
}

void exit_room(ConnectorService *service)
{
	MessageBlock mb(512);
	mb << 0;
	mb << 10000004;
	mb << 0;
	char *p=mb.base_ptr();
	*p = mb.data_len();

	//int send_len =::send(fd,(void*)mb.rd_ptr(),mb.data_len(),0);
	int send_len =service->send_msg(&mb,mb.data_len());
	std::cout << "send len:"<<send_len<<std::endl;

	MessageBlock recv_mb(4096);
	while(true)
	{
		recv_mb.reset();
		int recv_len = service->recv_msg(&recv_mb,recv_mb.size(),0);
		if(recv_len<0)
		{
			std::cout << "recv len error:"<<recv_len<<std::endl;
			break;
		}
		int len=0,cmd=0,result=0;
		recv_mb >> len >> cmd >> result;
		std::cout << "recv len:"<<recv_len<<"-len:"<<len
				<<"-cmd:"<<cmd<<"-result:"<<result<<std::endl;
	}
}

void switch_room(ConnectorService *service)
{
	MessageBlock mb(512);
	mb << 0;
	mb << 10000005;
	mb << 0;
	mb << 2;
	char *p=mb.base_ptr();
	*p = mb.data_len();

	//int send_len =::send(fd,(void*)mb.rd_ptr(),mb.data_len(),0);
	int send_len =service->send_msg(&mb,mb.data_len());
	std::cout << "send len:"<<send_len<<std::endl;

	MessageBlock recv_mb(4096);
	while(true)
	{
		recv_mb.reset();
		int recv_len = service->recv_msg(&recv_mb,recv_mb.size(),0);
		if(recv_len<0)
		{
			std::cout << "recv len error:"<<recv_len<<std::endl;
			break;
		}
		int len=0,cmd=0,result=0;
		recv_mb >> len >> cmd >> result;
		std::cout << "recv len:"<<recv_len<<"-len:"<<len
				<<"-cmd:"<<cmd<<"-result:"<<result<<std::endl;
	}
}

void enter_table(ConnectorService *service)
{
	MessageBlock mb(512);
	mb << 0;
	mb << 10000006;
	mb << 0;
	char *p=mb.base_ptr();
	*p = mb.data_len();

	//int send_len =::send(fd,(void*)mb.rd_ptr(),mb.data_len(),0);
	int send_len =service->send_msg(&mb,mb.data_len());
	std::cout << "send len:"<<send_len<<std::endl;

	MessageBlock recv_mb(4096);
	int recv_len=0;
	while(true)
	{
		recv_mb.reset();

		recv_len= service->recv_msg(&recv_mb,recv_mb.size(),0);
		if(recv_len<=0)
		{
			continue;
		}
		int len =0,cmd=0,result=0,len_count=0;
		while(len_count<recv_len)
		{
			recv_mb>>len ;
			MessageBlock mb(1024);
			mb.write(recv_mb.rd_ptr(),len-sizeof(int));
			recv_mb.rd_ptr(len-sizeof(int));

			mb >> cmd>>result;
			std::cout << "recv len:"<<recv_len<<"len:"<<len<<"cmd:"<<cmd<<std::endl;

			len_count +=len;
			if(cmd==STC_NOTIFY_OPERATE)
			{
				select_operation(&mb);
			}
		}
	}
}

void select_operation(MessageBlock *mb)
{
	int bring_chips =0,start=0,bet=0,call =0,check =0,all_in=0,fold=0;
	*mb >> bring_chips >> start >>bet>>call>>check >>all_in>>fold;
	std::cout <<"bring_chips:"<<bring_chips
			<<"--start:"<<start <<"--bet:"<<bet
			<<"--call:"<<call <<"--check:"<<check
			<<"--all_in:"<<all_in <<"--fold:"<<fold
			<<std::endl;



	if (bring_chips == 1)
	{
		int amount = 0;
		std::cout <<"bring_chips input amount:"<<std::endl;
		std::cin >> amount;

		MessageBlock mb(512);
		mb << 0;
		mb << 10000015;
		mb << 0;
		mb << amount;
		mb << 0;
		char *p = mb.base_ptr();
		*p = mb.data_len();
		int send_len =service->send_msg(&mb,mb.data_len());
		std::cout << "bring_chips send len:"<<send_len<<std::endl;

	}
	else
	{
		int cmd = 0;
		std::cout <<"1:start 2:bet 3:call 4:check 5:all_in 6:fold select operation:"<<std::endl;
		std::cin >> cmd;
		if(cmd<1 || cmd >6)
		{
			std::cout <<"1:start 2:bet 3:call 4:check 5:all_in 6:fold select operation:"<<std::endl;
			std::cin >> cmd;
		}
		if (cmd==1 && start == 1)
		{
			cmd= 10000008;
		}
		else if (cmd==2 && bet == 1)
		{
			cmd= 10000009;

			int amount = 0;
			std::cout << "bet input amount:" << std::endl;
			std::cin >> amount;
			MessageBlock send_mb(512);
			send_mb << 0;
			send_mb << cmd;
			send_mb << 0;
			send_mb << amount;
			char *p = send_mb.base_ptr();
			*p = send_mb.data_len();
			int send_len =service->send_msg(&send_mb,send_mb.data_len());
			std::cout << "bet send len:"<<send_len<<std::endl;
		}
		else if (cmd==3 && call == 1)
		{
			cmd= 10000013;
		}
		else if (cmd==4 && check == 1)
		{
			cmd= 10000014;
		}
		else if (cmd==5 && all_in == 1)
		{
			cmd= 10000011;

			MessageBlock send_mb(512);
			send_mb << 0;
			send_mb << cmd;
			send_mb << 0;
			char *p = send_mb.base_ptr();
			*p = send_mb.data_len();
			int send_len =service->send_msg(&send_mb,send_mb.data_len());
			std::cout << "all_in send len:"<<send_len<<std::endl;
		}
		else if (cmd==6 && fold == 1)
		{
			cmd= 10000012;
		}
		else
		{
			return ;
		}
	}
}

void exit_table(ConnectorService *service)
{
	MessageBlock mb(512);
	mb << 0;
	mb << 10000007;
	mb << 0;
	char *p=mb.base_ptr();
	*p = mb.data_len();

	//int send_len =::send(fd,(void*)mb.rd_ptr(),mb.data_len(),0);
	int send_len =service->send_msg(&mb,mb.data_len());
	std::cout << "send len:"<<send_len<<std::endl;

	MessageBlock recv_mb(4096);
	while(true)
	{
		recv_mb.reset();
		int recv_len = service->recv_msg(&recv_mb,recv_mb.size(),0);
		if(recv_len<0)
		{
			std::cout << "recv len error:"<<recv_len<<std::endl;
			break;
		}
		int len=0,cmd=0,result=0;
		recv_mb >> len >> cmd >> result;
		std::cout << "recv len:"<<recv_len<<"-len:"<<len
				<<"-cmd:"<<cmd<<"-result:"<<result<<std::endl;
	}
}

void test_packet(ConnectorService *service)
{
	MessageBlock mb(512);
	mb << 0;
	mb << 1;
	mb << 0;
	mb << account;
	mb << pwd;//std::string(password);
	char *p=mb.base_ptr();
	*p = mb.data_len();

	//for(int i=0;i<100000;i++)
		while(true)
	{
		int send_len =service->send_msg(&mb,mb.data_len());
		std::cout << "send len:"<<send_len<<std::endl;
		usleep(20);
	}
}
